<template>
  <div v-if="history" class="comp-option-edit-panel op-group">
    <div class="op-title">编辑-{{ history.data.label }}</div>
    <div class="option-item">
      <div v-if="subEditMode !== 'formulaColumn'" class="title-row">
        <span class="edit-label" :title="history.data.description">
          <template v-if="subEditMode !== 'mregeColumns'"
            >{{ history.data.col }}：
          </template>
          {{ history.data.description }}
        </span>
      </div>
      <div v-if="subEditMode === 'replaceKeyword'" class="sub-item">
        <span class="label edit-label">替换刷选内容为</span>
        <a-input
          v-model="bindData.replaceKeyword"
          lass="edit-replace-value"
          placeholder="Null"
          size="small"
        >
        </a-input>
      </div>
      <div v-if="subEditMode === 'replaceContent'" class="sub-item">
        <span class="label edit-label">替换单元格内容为</span>
        <a-input
          v-if="!isNumberColumn"
          v-model="bindData.replaceValue"
          size="small"
          placeholder="Null"
          class="edit-replace-value"
        >
        </a-input>
        <a-input-number
          v-else
          v-model="bindData.replaceValue"
          placeholder="Null"
          size="small"
          class="edit-replace-value number"
        >
        </a-input-number>
      </div>
      <div v-if="subEditMode === 'extractColumn'" class="sub-item">
        <span class="label edit-label">拆分新列名为</span>
        <a-input
          v-model="bindData.extractColumn"
          size="small"
          placeholder="Null"
          class="edit-replace-value"
        >
        </a-input>
      </div>
      <div v-if="subEditMode === 'splitColumns'" class="sub-item">
        <span class="label edit-label">拆分多列</span>
        <split-panel
          ref="splitPanel"
          v-model="bindData.splitColumns"
          :edit-bind-column="editBindColumn"
          :edit-value-column-name="editValueColumnName"
          :is-edit-mode="true"
          :split-mode="actionType"
        >
        </split-panel>
      </div>
      <div v-if="subEditMode === 'formulaColumn'">
        <formula-form
          ref="formulaInput"
          :formula-value="bindData.formulaColumn.formulaValue"
          :column-name="bindData.formulaColumn.columnName"
          :base-col="bindData.formulaColumn.baseCol"
          :table-name="tableName"
          @actiondone="doAction"
        ></formula-form>
      </div>
      <div v-if="subEditMode === 'mregeColumns'" class="sub-item">
        <span class="label edit-label">多列合并</span>
        <div class="merge-item-column">
          <span class="label">
            拼接字符串
          </span>
          <a-input
            v-model="bindData.mregeColumns.joinString"
            placeholder="null"
            size="small"
          ></a-input>
        </div>
        <div class="merge-item-column">
          <span class="label">
            合并后列名
          </span>
          <a-input
            v-model="bindData.mregeColumns.newColumnName"
            placeholder="null"
            size="small"
            @blur="onNewColumnNameBlur"
          ></a-input>
        </div>
      </div>
      <div class="detail-panel">
        <div class="button-row">
          <a-button class="op-btn-sub" size="small" @click="cancel"
            >取消</a-button
          >
          <a-button
            class="op-btn-sub"
            type="primary"
            size="small"
            @click="doOption"
            >确定</a-button
          >
        </div>
      </div>
    </div>
  </div>
</template>
<script lang="ts">
import { isArray, isFunction } from 'lodash'
import { Component, Prop, Vue, Watch } from 'vue-property-decorator'
import DataStore from '@/store/modules/dataview'
import { apiUpdateHistory } from '@/api/data-clean'
import SplitPanel from '../common/splitPanel.vue'
import FormulaForm from '../columns/formulaForm.vue'

/** 编辑操作类型 */
enum EditMode {
  replaceKeyword = 'replaceKeyword',
  replaceContent = 'replaceContent',
  extractColumn = 'extractColumn',
  splitColumns = 'splitColumns',
  mregeColumns = 'mregeColumns',
  formulaColumn = 'formulaColumn',
}

/** 操作后历史记录，点击编辑后的编辑面板组件 */
@Component({
  name: 'option-edit-panel',
  components: {
    SplitPanel,
    FormulaForm,
  },
})
/** 历史操作编辑面板，支持transfrom推荐出来的 replaceKeyword、replaceContent、extractColumn、splitColumns相关操作 */
export default class OptionEditPanel extends Vue {
  /**
   * 当前历史记录
   */
  @Prop({
    type: Object,
    default() {
      return null
    },
  })
  history!: Object

  /**
   * 当前table name
   */
  @Prop({
    type: String,
    default() {
      return ''
    },
  })
  tableName!: String | undefined
  /* 绑定数据 */
  bindData: any = {
    replaceValue: '',
    replaceKeyword: '',
    extractColumn: '',
    splitColumns: {
      separator: '',
      splitType: 1,
      splitNum: 2,
      columnName: [''],
    },
    mregeColumns: {
      joinString: '',
      newColumnName: '',
    },
    formulaColumn: {
      formulaValue: '',
      columnName: '',
      baseCol: '',
    },
  }

  /** 监听历史记录，变更后刷新绑定数据 */
  @Watch('history', {
    immediate: true,
    deep: true,
  })
  getHistroy(newValue: any) {
    this.$nextTick(() => {
      this.initBindData()
    })
    return newValue
  }

  /** 获取当前历史记录操作的列 */
  get editBindColumn() {
    const history = this.history as any
    return history !== null ? (history.data.col as string) : ''
  }

  /** 拆分列模式下, 历史记录中原本的拆分后的列名 */
  get editValueColumnName() {
    const history = this.history as any
    return history !== null && this.subEditMode === EditMode.splitColumns
      ? ([...history.data.newCol] as Array<string>)
      : []
  }

  /** 获取当前历史记录的action */
  get actionType() {
    const history = this.history as any
    return history !== null ? (history.data.actionType as string) : ''
  }

  /** 相关列是否为数值型 */
  get isNumberColumn() {
    const history = this.history as any
    if (this.history) {
      return DataStore.tableColumns.find((column) => {
        return (
          column.name === history.data.col &&
          ['decimal', 'int'].includes(column.desc || '')
        )
      })
    }
    return false
  }

  /** 根据当前历史记录获取当前的编辑模式 */
  get subEditMode() {
    /* eslint-disable */
    if (/ReplaceKeyword$/.test(this.actionType)) {
      return EditMode.replaceKeyword
    } else if (/ReplaceContent$/.test(this.actionType)) {
      return EditMode.replaceContent
    } else if (/Reset$/.test(this.actionType)) {
      return EditMode.replaceContent
    } else if (/ExtractColumn$/.test(this.actionType)) {
      return EditMode.extractColumn
    } else if (/SplitColumns$/.test(this.actionType)) {
      return EditMode.splitColumns
    } else if (/columnMergeColumns$/.test(this.actionType)) {
      return EditMode.mregeColumns
    } else if (/formulaColumn$/.test(this.actionType)) {
      const history = this.history as any
      //  目前支持区分大小写的列名
      DataStore.setEditedFormulaColName(history.data.newColumn)
      return EditMode.formulaColumn
    }
    return ''
  }

  /** 选中节点 */
  get selectNode() {
    return DataStore.selectNode
  }

  private get formulaInstance() {
    return this.$refs.formulaInput as any
  }

  /** 绑定数据 */
  initBindData() {
    if (this.actionType.endsWith('formulaColumn')) {
      DataStore.setShowColumnIndex(true)
    } else {
      DataStore.setShowColumnIndex(false)
    }
    const history = this.history as any
    switch (this.subEditMode) {
      case EditMode.replaceKeyword:
        this.$set(this.bindData, 'replaceKeyword', history.data.replaceValue)
        break
      case EditMode.replaceContent:
        this.$set(this.bindData, 'replaceValue', history.data.setValue)
        break
      case EditMode.extractColumn:
        this.$set(this.bindData, 'extractColumn', history.data.newCol)
        break
      case EditMode.splitColumns:
        this.$set(this.bindData, 'splitColumns', {
          separator: '',
          splitType: 1,
          splitNum: history.data.splitNum,
          columnName: [...history.data.newCol],
        })
        break
      case EditMode.mregeColumns:
        this.$set(this.bindData, 'mregeColumns', {
          joinString: history.data.separator,
          newColumnName: history.data.newCol,
        })
        break
      case EditMode.formulaColumn:
        this.$set(this.bindData, 'formulaColumn', {
          formulaValue: history.data.formula,
          columnName: history.data.newColumn,
          baseCol: history.data.col,
        })
        break
      default:
        console.error(
          `initBindData error: not sopourt mode ${this.subEditMode}`
        )
        break
    }
  }

  /** 取消 */
  cancel() {
    DataStore.setVRPanelShow(false)
    DataStore.setVrEditTrigger(-1)
    DataStore.setShowColumnIndex(false)
  }
  // 自动标准化默认值，用于填充模板位置
  autoTransNull(data: undefined | null | string) {
    return ['', null, undefined].includes(data) ? 'null' : data
  }

  /** 获取查询参数 */
  getUpdateQuery() {
    const histroy = this.history as any
    const data = { ...histroy.data }
    delete data.gmtCreate
    delete data.status
    const result = {
      data,
      projectId: histroy.projectId,
      taskId: histroy.taskId,
      taskName: histroy.taskName,
    }
    switch (this.subEditMode) {
      case EditMode.replaceKeyword:
        // 模板示例：把包含 crime 的单元格替换为 {{value}}
        result.data.description = (
          (result.data.descriptionTpl as string) || ''
        ).replace('{{value}}', this.bindData.replaceKeyword)
        result.data.replaceValue = this.bindData.replaceKeyword
        break
      case EditMode.replaceContent:
        // 模板示例：把包含 test2 单元格进行赋值为 {{value}}
        result.data.description = (
          (result.data.descriptionTpl as string) || ''
        ).replace('{{value}}', this.bindData.replaceValue)
        result.data.setValue = this.bindData.replaceValue
        break
      case EditMode.extractColumn:
        // 模板示例： 将刷选内容 test2 抽取新列 {{value}}
        result.data.description = (
          (result.data.descriptionTpl as string) || ''
        ).replace('{{value}}', this.bindData.extractColumn)
        result.data.newCol = this.bindData.extractColumn
        break
      case EditMode.splitColumns:
        // 模板示例： 以 test2拆分，取前 {{splitNum}}列,列名 {{columnNames}}
        result.data.description = (result.data.descriptionTpl as string)
          .replace('{{splitNum}}', this.bindData.splitColumns.splitNum)
          .replace(
            '{{columnNames}}',
            (this.bindData.splitColumns.columnName as Array<string>).join(',')
          )
        result.data.splitNum = this.bindData.splitColumns.splitNum
        result.data.newCol = this.bindData.splitColumns.columnName
        break
      case EditMode.mregeColumns:
        // 模板示例： 合并名：{{newColumnName}}，分隔符{{joinString}}，来自：sp_字段1、sp_字段2
        result.data.description = (result.data.descriptionTpl as string)
          .replace(
            '{{newColumnName}}',
            this.bindData.mregeColumns.newColumnName
          )
          .replace('{{joinString}}', this.bindData.mregeColumns.joinString)
        result.data.separator = this.bindData.mregeColumns.joinString
        result.data.newCol = this.bindData.mregeColumns.newColumnName
        break
      default:
        console.error(`not soport mode ${this.subEditMode}`)
        break
    }
    return result
  }

  /** 验证拆分字段 */
  validateSplitPanel(): Promise<any> {
    return new Promise((resolve, reject) => {
      // 如果为非字段拆分模式, 直接返回
      if (this.subEditMode !== EditMode.splitColumns) {
        resolve(true)
      } else {
        let panel = this.$refs.splitPanel
        panel = isArray(panel) ? (panel as Array<any>)[0] : panel
        if (!panel) {
          reject(new Error('panel is not found'))
        } else if (isFunction((panel as any).validate)) {
          const result = (panel as any).validate()
          if (result) {
            resolve(result)
          } else {
            reject(result)
          }
        } else {
          reject(new Error('panel.validate is not a function'))
        }
      }
    })
  }

  /** 新字段失去焦点 */
  onNewColumnNameBlur() {
    const newColumnName = this.bindData.mregeColumns.newColumnName
    if ('' === newColumnName) {
      this.$set(
        this.bindData.mregeColumns,
        'newColumnName',
        (this.history as any).data.newCol || ''
      )
    }
  }

  /** 更新清洗历史 */
  updateHistory(data: any) {
    apiUpdateHistory({
      data,
    })
      .then((response) => {
        if (response.data.code === 100) {
          DataStore.setVrEditTrigger(-1)
          // 清空数据
          DataStore.setTableData({
            head: [],
            data: [], // 清空
          })
          // 清空填入的内容
          DataStore.resetVrSettingValues()
          DataStore.refreshTaskQueryById(this.selectNode.id).then(() => {
            DataStore.getHistoryList() // 刷新历史记录
            DataStore.setConfirmEditTime(+new Date()) // 更新时间，触发后续节点的更新
            DataStore.setIsEditHistory(false)
            this.$message.success('操作成功')
          })
        }
      })
      .catch((error) => {
        console.log('error', error)
      })
  }

  /** 确定 */
  doOption() {
    //  当 编辑 公式新列  的历史时
    if (this.subEditMode === 'formulaColumn') {
      this.formulaInstance.doOption()
      return
    }
    this.validateSplitPanel()
      .then(() => {
        this.updateHistory(this.getUpdateQuery())
      })
      .catch((error) => {
        console.log('error', error)
      })
  }
  //  处理 更新公式清洗操作
  doAction(actionInfo: any) {
    DataStore.setShowColumnIndex(false)
    const histroy = this.history as any
    const data = { ...actionInfo }
    const result = {
      data,
      projectId: histroy.projectId,
      taskId: histroy.taskId,
      taskName: histroy.taskName,
    }

    this.updateHistory(result)
  }
}
</script>
<style lang="less" scoped>
@import url('../op.less');
</style>
